﻿Imports System.Collections.Specialized
Imports System.Reflection
Public Class Toolbox
    Public Shared Sub CopyDirectory(ByVal SourcePath As String, ByVal DestPath As String, Optional ByVal Overwrite As Boolean = False)
        Dim SourceDir As DirectoryInfo = New DirectoryInfo(SourcePath)
        Dim DestDir As DirectoryInfo = New DirectoryInfo(DestPath)

        ' the source directory must exist, otherwise throw an exception
        If SourceDir.Exists Then
            ' if destination SubDir's parent SubDir does not exist throw an exception
            If Not DestDir.Parent.Exists Then
                Throw New DirectoryNotFoundException _
                    ("Destination directory does not exist: " + DestDir.Parent.FullName)
            End If

            If Not DestDir.Exists Then
                DestDir.Create()
            End If

            ' copy all the files of the current directory
            Dim ChildFile As FileInfo
            For Each ChildFile In SourceDir.GetFiles()
                If Overwrite Then
                    ChildFile.CopyTo(Path.Combine(DestDir.FullName, ChildFile.Name), True)
                Else
                    ' if Overwrite = false, copy the file only if it does not exist
                    ' this is done to avoid an IOException if a file already exists
                    ' this way the other files can be copied anyway...
                    If Not File.Exists(Path.Combine(DestDir.FullName, ChildFile.Name)) Then
                        ChildFile.CopyTo(Path.Combine(DestDir.FullName, ChildFile.Name), False)
                    End If
                End If
            Next

            ' copy all the sub-directories by recursively calling this same routine
            Dim SubDir As DirectoryInfo
            For Each SubDir In SourceDir.GetDirectories()
                CopyDirectory(SubDir.FullName, Path.Combine(DestDir.FullName, _
                    SubDir.Name), Overwrite)
            Next
        Else
            Throw New DirectoryNotFoundException("Source directory does not exist: " + SourceDir.FullName)
        End If
    End Sub
    Public Shared Function TempPath() As String
        Return System.IO.Path.GetTempPath
    End Function
    Public Shared Function StylesPath() As String
        Return TempPath() & My.Settings.StylesPath
    End Function
    Public Shared Function SettingsPath() As String
        Return TempPath() & My.Settings.SettingsPath
    End Function
    Public Shared Function DefaultStylesPath() As String
        Return TempPath() & My.Settings.DefaultStylesPath
    End Function
    Public Shared Function CssImageDir() As String
        Return "file:///" & (TempPath() & My.Settings.ImagePath).Replace("\", "/") & ""
    End Function
    Public Shared Function GetRecentSites() As String()
        If My.Settings.RecentSites Is Nothing Then
            My.Settings.RecentSites = New StringCollection
        End If
        If My.Settings.RecentSites.Count > 0 Then
            Dim sites(My.Settings.RecentSites.Count - 1) As String
            My.Settings.RecentSites.CopyTo(sites, 0)
            Return sites
        Else
            Return New String() {}
        End If
    End Function
    Public Shared Function GetRecentThemes() As Dictionary(Of String, String)
        If My.Settings.RecentThemes Is Nothing Then
            My.Settings.RecentThemes = New StringCollection
        End If
        If My.Settings.RecentThemes.Count > 0 Then
            Dim dict As New Dictionary(Of String, String)
            For Each s As String In My.Settings.RecentThemes
                dict.Add(s.Split(";")(0), s.Split(";")(1))
            Next
            Return dict
        Else
            Return New Dictionary(Of String, String)
        End If
    End Function
    Public Shared Sub AddRecentTheme(ByVal Theme As String, ByVal Path As String)
        Dim entry As String = Theme & ";" & Path
        My.Settings.RecentThemes.Remove(entry)
        My.Settings.RecentThemes.Add(entry)
        If My.Settings.RecentThemes.Count > 10 Then
            My.Settings.RecentThemes.Remove(0)
        End If
        My.Settings.Save()
    End Sub
    Public Shared Sub RemoveRecentTheme(ByVal Theme As String, ByVal Path As String)
        Dim entry As String = Theme & ";" & Path
        My.Settings.RecentThemes.Remove(entry)
    End Sub
    Public Shared Sub AddRecentSite(ByVal Site As String)
        If Not My.Settings.RecentSites.Contains(Site.ToLower) Then
            My.Settings.RecentSites.Add(Site)
            If My.Settings.RecentSites.Count > 10 Then
                My.Settings.RecentSites.Remove(0)
            End If
            My.Settings.Save()
        End If
    End Sub
    Friend Shared Function GetHexColor(ByVal colorObj As System.Drawing.Color) As String
        Return "#" & Complete(Hex(colorObj.R)) & Complete(Hex(colorObj.G)) & Complete(Hex(colorObj.B))
    End Function
    Friend Shared Function GetHexAlphaColor(ByVal colorObj As System.Drawing.Color) As String
        Return "#" & Complete(Hex(colorObj.A)) & Complete(Hex(colorObj.R)) & Complete(Hex(colorObj.G)) & Complete(Hex(colorObj.B))
    End Function
    Friend Shared Function GetColor(ByVal hex As String) As Color
        Return ColorTranslator.FromHtml(hex)
    End Function
  
    Private Shared Function Complete(ByVal input As String)
        If input.Length = 1 Then
            input = "0" & input
        End If
        Return input
    End Function
    Public Shared Function GetSmallColorIcon(ByVal color As Color) As Bitmap
        Return GetColorIcon(16, 16, color)
    End Function
    Public Shared Function GetLargeColorIcon(ByVal color As Color) As Bitmap
        Return GetColorIcon(32, 32, color)
    End Function
    Private Shared Function GetColorIcon(ByVal Width As Integer, ByVal Height As Integer, ByVal color As Color) As Bitmap
        Dim bmp As New Bitmap(Width, Height)
        Dim g As Graphics = Graphics.FromImage(bmp)
        g.FillRectangle(New SolidBrush(color), New Rectangle(0, 0, Width, Height))
        g.Dispose()
        Return bmp
    End Function
    Public Shared Function GetImageColor(ByVal ImageName As String, ByVal x As Integer, ByVal y As Integer) As Color
        If File.Exists(TempPath() & My.Settings.ImagePath & ImageName) Then
            Dim bmp As New Bitmap(TempPath() & My.Settings.ImagePath & ImageName)
            Dim c As Color = bmp.GetPixel(x, y)
            Try
                bmp.Dispose()
            Catch ex As Exception
            End Try
            Return c
        Else
            Return Color.White
        End If
    End Function
    Public Shared Function GetImageHeight(ByVal ImageName As String) As Integer
        If File.Exists(TempPath() & My.Settings.ImagePath & ImageName) Then
            Dim bmp As New Bitmap(TempPath() & My.Settings.ImagePath & ImageName)
            Dim height As Integer = bmp.Height
            Try
                bmp.Dispose()
            Catch ex As Exception
            End Try
            Return height
        Else
            Return 0
        End If
    End Function
  
End Class
Public Class RGBHSL
    Public Class HSL
        Public Sub New()
            _h = 0
            _s = 0
            _l = 0
        End Sub 'New
        Private _h As Double
        Private _s As Double
        Private _l As Double
        Public Property H() As Double
            Get
                Return _h
            End Get
            Set(ByVal value As Double)
                _h = value
                _h = IIf(_h > 1, 1, IIf(_h < 0, 0, _h))
            End Set
        End Property
        Public Property S() As Double
            Get
                Return _s
            End Get
            Set(ByVal value As Double)
                _s = value
                _s = IIf(_s > 1, 1, IIf(_s < 0, 0, _s))
            End Set
        End Property
        Public Property L() As Double
            Get
                Return _l
            End Get
            Set(ByVal value As Double)
                _l = value
                _l = IIf(_l > 1, 1, IIf(_l < 0, 0, _l))
            End Set
        End Property
    End Class 'HSL
    Public Sub New()

    End Sub 'New
    '/ <summary>
    '/ Sets the absolute brightness of a colour
    '/ </summary>
    '/ <param name="c">Original colour</param>
    '/ <param name="brightness">The luminance level to impose</param>
    '/ <returns>an adjusted colour</returns>
    Public Shared Function SetBrightness(ByVal c As Color, ByVal brightness As Double) As Color
        Dim hsl As HSL = RGB_to_HSL(c)
        hsl.L = brightness
        Return HSL_to_RGB(hsl)
    End Function 'SetBrightness
    '/ <summary>
    '/ Modifies an existing brightness level
    '/ </summary>
    '/ <remarks>
    '/ To reduce brightness use a number smaller than 1. To increase brightness use a number larger tnan 1
    '/ </remarks>
    '/ <param name="c">The original colour</param>
    '/ <param name="brightness">The luminance delta</param>
    '/ <returns>An adjusted colour</returns>
    Public Shared Function ModifyBrightness(ByVal c As Color, ByVal brightness As Double) As Color
        Dim hsl As HSL = RGB_to_HSL(c)
        hsl.L *= brightness
        Return HSL_to_RGB(hsl)
    End Function 'ModifyBrightness
    '/ <summary>
    '/ Sets the absolute saturation level
    '/ </summary>
    '/ <remarks>Accepted values 0-1</remarks>
    '/ <param name="c">An original colour</param>
    '/ <param name="Saturation">The saturation value to impose</param>
    '/ <returns>An adjusted colour</returns>
    Public Shared Function SetSaturation(ByVal c As Color, ByVal Saturation As Double) As Color
        Dim hsl As HSL = RGB_to_HSL(c)
        hsl.S = Saturation
        Return HSL_to_RGB(hsl)
    End Function 'SetSaturation
    '/ <summary>
    '/ Modifies an existing Saturation level
    '/ </summary>
    '/ <remarks>
    '/ To reduce Saturation use a number smaller than 1. To increase Saturation use a number larger tnan 1
    '/ </remarks>
    '/ <param name="c">The original colour</param>
    '/ <param name="Saturation">The saturation delta</param>
    '/ <returns>An adjusted colour</returns>
    Public Shared Function ModifySaturation(ByVal c As Color, ByVal Saturation As Double) As Color
        Dim hsl As HSL = RGB_to_HSL(c)
        hsl.S *= Saturation
        Return HSL_to_RGB(hsl)
    End Function 'ModifySaturation
    '/ <summary>
    '/ Sets the absolute Hue level
    '/ </summary>
    '/ <remarks>Accepted values 0-1</remarks>
    '/ <param name="c">An original colour</param>
    '/ <param name="Hue">The Hue value to impose</param>
    '/ <returns>An adjusted colour</returns>
    Public Shared Function SetHue(ByVal c As Color, ByVal Hue As Double) As Color
        Dim hsl As HSL = RGB_to_HSL(c)
        hsl.H = Hue
        Return HSL_to_RGB(hsl)
    End Function 'SetHue
    '/ <summary>
    '/ Modifies an existing Hue level
    '/ </summary>
    '/ <remarks>
    '/ To reduce Hue use a number smaller than 1. To increase Hue use a number larger tnan 1
    '/ </remarks>
    '/ <param name="c">The original colour</param>
    '/ <param name="Hue">The Hue delta</param>
    '/ <returns>An adjusted colour</returns>
    Public Shared Function ModifyHue(ByVal c As Color, ByVal Hue As Double) As Color
        Dim hsl As HSL = RGB_to_HSL(c)
        hsl.H *= Hue
        Return HSL_to_RGB(hsl)
    End Function 'ModifyHue
    '/ <summary>
    '/ Converts a colour from HSL to RGB
    '/ </summary>
    '/ <remarks>Adapted from the algoritm in Foley and Van-Dam</remarks>
    '/ <param name="hsl">The HSL value</param>
    '/ <returns>A Color structure containing the equivalent RGB values</returns>
    Public Shared Function HSL_to_RGB(ByVal hsl As HSL) As Color
        Dim r As Double = 0
        Dim g As Double = 0
        Dim b As Double = 0
        Dim temp1, temp2 As Double
        If hsl.L = 0 Then
            r = 0
            g = 0
            b = 0
        Else
            If hsl.S = 0 Then
                r = hsl.L
                g = hsl.L
                b = hsl.L
            Else
                temp2 = IIf(hsl.L <= 0.5, hsl.L * (1.0 + hsl.S), hsl.L + hsl.S - hsl.L * hsl.S)
                temp1 = 2.0 * hsl.L - temp2
                Dim t3() As Double = {hsl.H + 1.0 / 3.0, hsl.H, hsl.H - 1.0 / 3.0}
                Dim clr() As Double = {0, 0, 0}
                Dim i As Integer
                For i = 0 To 2
                    If t3(i) < 0 Then
                        t3(i) += 1.0
                    End If
                    If t3(i) > 1 Then
                        t3(i) -= 1.0
                    End If
                    If 6.0 * t3(i) < 1.0 Then
                        clr(i) = temp1 + (temp2 - temp1) * t3(i) * 6.0
                    ElseIf 2.0 * t3(i) < 1.0 Then
                        clr(i) = temp2
                    ElseIf 3.0 * t3(i) < 2.0 Then
                        clr(i) = temp1 + (temp2 - temp1) * (2.0 / 3.0 - t3(i)) * 6.0
                    Else
                        clr(i) = temp1
                    End If
                Next i
                r = clr(0)
                g = clr(1)
                b = clr(2)
            End If
        End If
        Return Color.FromArgb(CInt(255 * r), CInt(255 * g), CInt(255 * b))
    End Function 'HSL_to_RGB
    '
    '/ <summary>
    '/ Converts RGB to HSL
    '/ </summary>
    '/ <remarks>Takes advantage of whats already built in to .NET by using the Color.GetHue, Color.GetSaturation and Color.GetBrightness methods</remarks>
    '/ <param name="c">A Color to convert</param>
    '/ <returns>An HSL value</returns>
    Public Shared Function RGB_to_HSL(ByVal c As Color) As HSL
        Dim hsl As New HSL()
        hsl.H = c.GetHue() / 360.0 ' we store hue as 0-1 as opposed to 0-360
        hsl.L = c.GetBrightness()
        hsl.S = c.GetSaturation()
        Return hsl
    End Function 'RGB_to_HSL
End Class 'RGBHSL

